import jason.asSyntax.*;
import jason.environment.Environment;
import jason.environment.grid.Location;
import java.util.logging.Logger;

public class HouseEnv extends Environment {

    // common literals
    public static final Literal of  = Literal.parseLiteral("open(fridge)");
    public static final Literal clf = Literal.parseLiteral("close(fridge)");
    public static final Literal gb  = Literal.parseLiteral("get(beer)");
    public static final Literal hb  = Literal.parseLiteral("hand_in(beer)");
    public static final Literal sb  = Literal.parseLiteral("sip(beer)");
    public static final Literal hob = Literal.parseLiteral("has(owner,beer)");

    public static final Literal af = Literal.parseLiteral("at(robot,fridge)");
    public static final Literal ao = Literal.parseLiteral("at(robot,owner)");
    
    static Logger logger = Logger.getLogger(HouseEnv.class.getName());
    HouseModel model; // the model of the grid
    
    @Override
    public void init(String[] args) {
        model = new HouseModel();
        
        if (args.length == 1 && args[0].equals("gui")) { 
            HouseView view  = new HouseView(model);
            model.setView(view);
        }
        
        updatePercepts();
    }
    
    /** creates the agents percepts based on the HouseModel */
    void updatePercepts() {

        for(int i = 0; i < model.objectives.size(); i++){
			clearPercepts("car" + (i+1));
			Location lCar = model.getAgPos(i);
			addPercept("car" + (i+1), Literal.parseLiteral("my_speed("+ model.mySpeed.get(i) +")"));
			addPercept("car" + (i+1), Literal.parseLiteral("my_road("+ model.myRoad.get(i) +")"));
			int bc = model.recFindBackCar(i);
			if (bc > -1)
				addPercept("car" + (i+1), Literal.parseLiteral("back_car(car"+ (bc+ 1) +")"));
			if(lCar.x == 40){
				addPercept("car" + (i+1), Literal.parseLiteral("chegou"));
			}
			if(lCar.equals(model.objectives.get(i))){
				addPercept("car" + (i+1), Literal.parseLiteral("at(crossroad)"));
				int best_distance = 9999;
				int short_way = 0;
				for(int j=0; j < model.roads.size(); j = j + 2){
					if(model.objectives.get(i).equals(model.roads.get(j))){
						addPercept("car" + (i+1), Literal.parseLiteral("road_choice(" + j + ")"));
						addPercept("car" + (i+1), Literal.parseLiteral("road_best_dist(" + j + "," + model.roadsBestDist.get(j/2) + ")"));

						if( model.roadsBestDist.get(j/2) < best_distance ){
							best_distance = model.roadsBestDist.get(j/2);
							short_way = j;
						}
					}
				}
				if (best_distance != 9999)
					addPercept("car" + (i+1), Literal.parseLiteral("shortest_way(" + short_way + ")"));
			}else{
				addPercept("car" + (i+1), Literal.parseLiteral("at(road)"));
			}
		}
    }
    

    @Override
    public boolean executeAction(String ag, Structure action) {
        //System.out.println("["+ag+"] doing: "+action);
        boolean result = false;
        if (action.equals(Literal.parseLiteral("move"))) {
            result = model.moveTowards(Integer.parseInt(ag.substring(3)) - 1);
        } else if (action.getFunctor().equals("goto_road")) {
            Integer l = Integer.parseInt(action.getTerm(0).toString());
			model.changeRoad(Integer.parseInt(ag.substring(3)) - 1, l);
        } else {
            logger.info("Failed to execute action "+action);
        }

        if (result) {
            updatePercepts();
            try { Thread.sleep(100); } catch (Exception e) {}
        }
        return result;
    }
}
